package com.hiss.basic.starter.websocket.model;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.hiss.basic.starter.core.exception.BusinessException;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@Data
public class MessageModel implements Serializable {

    private static final long serialVersionUID = 1L;

    private String messageId;

    private MessageType type;

    private Map<String, Set<String>> receivers;

    private String payload;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;

    public enum MessageType {
        USER, CHANNEL, CHANNEL_USER, BROADCAST
    }

    public MessageModel() {
        this.messageId = generateMessageId();
        this.timestamp = LocalDateTime.now();
    }

    /**
     * 构建消息
     * <p>
     * type: BROADCAST
     *
     * @param payload 消息内容
     */
    public static MessageModel of(String payload) {
        MessageModel model = new MessageModel();
        model.type = MessageType.BROADCAST;
        model.payload = payload;
        return model;
    }

    /**
     * 构建消息
     *
     * @param type     消息类型 USER || CHANNEL
     * @param payload  消息内容
     * @param receiver 频道/用户 ["user_id_1", "user_id_2", "user_id_3"] || ["channel_1", "channel_2", "channel_3"]
     */
    public static MessageModel of(MessageType type, String payload, String... receiver) {
        if (!ObjectUtil.equal(MessageType.USER, type) && !ObjectUtil.equal(MessageType.CHANNEL, type)) {
            throw new BusinessException("此方法不支持的消息类型 messageType=" + type);
        }
        MessageModel model = new MessageModel();
        model.type = type;

        Map<String, Set<String>> receivers = new HashMap<>();
        receivers.put("receivers", CollectionUtil.newHashSet(receiver));

        model.receivers = receivers;
        model.payload = payload;
        return model;
    }

    /**
     * 构建消息
     * <p>
     * type: CHANNEL_USER
     *
     * @param payload   消息内容
     * @param receivers 接收方 {"channel_name": ["user_id_1", "user_id_2", "user_id_3"]}
     */
    public static MessageModel of(String payload, Map<String, Set<String>> receivers) {
        MessageModel model = new MessageModel();
        model.type = MessageType.CHANNEL_USER;
        model.receivers = receivers;
        model.payload = payload;
        return model;
    }

    public static String generateMessageId() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}
